package org.ww.order.service.impl;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
import org.ww.order.entity.OrderEntity;
import org.ww.order.entity.OrderReturnReasonEntity;

import java.io.IOException;

/**
 * @program: gmall
 * @description:
 * @author: ww
 * @RabbitListener 可以标注在类和方法上
 *
 *
 * 1、队列可以有很多消费者进行监听，但是一条消息只能被一个消费者接收到（除了广播模式）
 * 2、消费者收到一条消息后，在当前消息没处理完的情况下是不会去接收下一条消息的
 * @create: 2024-10-28 11:19
 **/

@Slf4j
@Service
@RabbitListener(queues = {"hello-java-queue"})
public class RabbitmqListenerTestServiceImpl {

    /**
     * @RabbitHandler ： 解决当消息发送者发送不同实体类型的消息时，可以使用该注解定义多个方法，接收具体实体类型的参数
     * 方法的参数可以有以下种类：
     * @param message：原生message消息，包含消息体body，消息属性：messageProperties，
     * @param orderEntity：T<泛型> 根据发送消息的实体类来决定此处的接收消息实体类
     * @param channel 通道
     */
    @RabbitHandler
    public void messageListenerA(Message message, OrderEntity orderEntity, Channel channel){
        log.info("orderEntity接收到的原生消息：【{}】",message);
        log.info("orderEntity实体类:[{}]",orderEntity);
        //消息序号按递增方式产生
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("orderEntity手动确认模式deliveryTag==>"+deliveryTag);
        try {
            if(deliveryTag%2==0){
                //第二个参数是 是否批量签收，这里拒绝掉，一次只签收一条
                channel.basicAck(deliveryTag,false);
            }else {
                /**
                 * basicNack 比 basicReject方法多了一个参数：是否批量拒绝
                 * 第一个参数：消息id
                 * 第二个参数：是否批量拒绝
                 * 第三个参数：发送失败的消息是否重新投放到队列，如果为false则直接将消息丢弃
                 */
                channel.basicNack(deliveryTag,false,true);
                System.out.println("orderEntity发送失败，拒绝消息deliveryTag==>"+deliveryTag);
//                channel.basicReject();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @RabbitHandler
    public void messageListenerB(Message message, OrderReturnReasonEntity orderReturnReasonEntity, Channel channel){
        log.info("orderReturnReasonEntity接收到的原生消息：【{}】",message);
        log.info("orderReturnReasonEntity实体类:[{}]",orderReturnReasonEntity);
    }

}
